package com.roamer.audition.web.security.handler;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.roamer.audition.common.constants.CommonConstants;
import com.roamer.audition.web.security.service.JwtUserService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * JWT认证成功处理器
 *
 * @author roamer
 * @version v1.0
 * @date 2020/4/20 16:41
 */
public class JwtRefreshSuccessHandler implements AuthenticationSuccessHandler {

    //刷新间隔5分钟
    private static final int tokenRefreshInterval = 300;

    private final JwtUserService jwtUserService;

    public JwtRefreshSuccessHandler(JwtUserService jwtUserService) {
        this.jwtUserService = jwtUserService;
    }


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        DecodedJWT jwt = (DecodedJWT) authentication.getCredentials();
        // 判断是否需要刷新
        if (shouldTokenRefresh(jwt.getIssuedAt())) {
            String newToken = jwtUserService.generateToken((UserDetails) authentication.getPrincipal());
            response.setHeader(CommonConstants.TOKEN_HEADER, newToken);
        }
    }

    /**
     * 是否刷新token
     *
     * @param issueAt token过期时间
     * @return {@code true} 返回true时刷新
     */
    protected boolean shouldTokenRefresh(Date issueAt) {
        LocalDateTime issueTime = LocalDateTime.ofInstant(issueAt.toInstant(), ZoneId.systemDefault());
        return LocalDateTime.now().minusSeconds(tokenRefreshInterval).isAfter(issueTime);
    }
}
